#! /usr/bin/env python
"""Asterisk AGI server for use from the dialplan

You use an asterisk AGI like this from extensions.conf:

	exten => 1000,3,AGI(agi.py)
"""

from twisted.internet import protocol, defer
from starpy import fastagi
import logging

log = logging.getLogger( 'AgiEx' )

# original file ? 

class FastAGIProtocolEx(fastagi.FastAGIProtocol):
    """Protocol for the interfacing with the Asterisk FastAGI application"""
    def __init__( self, *args, **named ):
        """Initialise the AMIProtocol, arguments are ignored"""
        self.messageCache = []
        self.variables = {}
        self.pendingMessages = []

        fastagi.log.setLevel(logging.ERROR)
        log.setLevel(logging.ERROR)

    def setVariable( self, variable, value ):
        """Set given channel variable to given value
        returns deferred integer result code
        """
        #command = "SET VARIABLE %s %r"%( variable, value )
        command = "SET VARIABLE %s %s"%( variable, value )
        return self.sendCommand( command ).addCallback( self.resultAsInt )

    def getVariables(self, *variables):
        """
        Retrieve the given variables
        """
        def getVariable():
            def onGetVariableErr(reason):
                log.debug('onGetVariableErr var=%s reason=%s' % (varname, reason))
                res_variables[varname] = None # varname
                getVariable()
            def onGetVariableOk(result):
                log.debug('onGetVariableOk var=%s result=%s' % (varname, result))
                res_variables[varname] = result # varname
                getVariable()

            if not len(variables):
                return df_ret.callback(res_variables)
            else:
                varname = variables.pop(0) # varname
                df = self.getVariable(varname)
                df.addCallbacks(onGetVariableOk, onGetVariableErr)
                return df

        variables = list(variables)
        log.debug('getVariable(%s) start' % variables)
        res_variables = {}
        df_ret = defer.Deferred()
        getVariable()
        return df_ret

    def setVariables(self, **variables):
        """
        Set given variables to given values
        """
        def setVariable():
            def onSetVariableOk(result):
                log.debug('onSetVariableOk result=%s' % result)
                res_variables[keyval[0]] = True # keyval
                setVariable()
            def onSetVariableErr(reason):
                log.debug('onSetVariableErr reason=%s' % reason)
                res_variables[keyval[0]] = True # keyval
                setVariable()

            if not len(variables):
                return df_ret.callback(res_variables)
            else:
                keyval = variables.popitem() # keyval
                df = self.setVariable(keyval[0], keyval[1])
                df.addCallbacks(onSetVariableOk, onSetVariableErr)
                return df

        log.debug('setVariables(%s) start' % variables)
        res_variables = {}
        df_ret = defer.Deferred()
        setVariable()
        return df_ret

class FastAGIFactory( protocol.Factory ):
    """Factory generating FastAGI server instances
    """
    protocol = FastAGIProtocolEx
    def __init__( self, mainFunction):
        """Initialise the factory
        mainFunction -- function taking a connected FastAGIProtocol instance 
        this is the function that's run when the Asterisk server connects.
        """
        self.mainFunction = mainFunction


if __name__ == "__main__":
    bc = bc_ast()
    reactor.run()
